
package GUI;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.swing.JPanel;


public class Obstaculos extends JPanel {

    List<Quadrado> obstaculos = new ArrayList<Quadrado>(); 
    private int ua;

    public void desenhaGrig(Graphics g, int unidadeDeArea)
    {
        this.ua = unidadeDeArea;
        g.setColor(Color.darkGray);
        for (int x = 0; x <= 2100; x += ua) {
            g.drawLine(x, 0, x, 2100);
        }
        for (int y = 0; y <= 2100; y += ua) {
            g.drawLine(0, y, 2100, y);
        }
    }

    public void desenhaGrig1(Graphics g, int unidadeDeArea)
    {
        this.ua = unidadeDeArea;
        g.setColor(Color.darkGray);
        for (int x = 0; x <= 2100; x += 4*ua) {
            g.drawLine(x, 0, x, 2100);
        }
        for (int y = 0; y <= 2100; y += 4*ua) {
            g.drawLine(0, y, 2100, y);
        }
    }

    public void desenhaGrig2(Graphics g, int unidadeDeArea)
    {
        this.ua = unidadeDeArea;
        g.setColor(Color.darkGray);
        for (int x = 0; x <= 2100; x += 8*ua) {
            g.drawLine(x, 0, x, 2100);
        }
        for (int y = 0; y <= 2100; y += 8*ua) {
            g.drawLine(0, y, 2100, y);
        }
    }

    public void desenhaGrig3(Graphics g, int unidadeDeArea)
    {
        this.ua = unidadeDeArea;
        g.setColor(Color.darkGray);
        for (int x = 0; x <= 2100; x += 16*ua) {
            g.drawLine(x, 0, x, 2100);
        }
        for (int y = 0; y <= 2100; y += 16*ua) {
            g.drawLine(0, y, 2100, y);
        }
    }

    public void desenhaObstaculos(Graphics g) {
        List<Quadrado> aux;
        aux = obstaculos;

        if (!aux.isEmpty()) {
            for (Quadrado obj : aux) {
                g.setColor(obj.getCor());
                g.fillPolygon(obj.getX(), obj.getY(), obj.getX().length);
                g.setColor(Color.BLACK);
                g.drawPolygon(obj.getX(), obj.getY(), obj.getX().length);
            }
        }
    }

    public void desenhaExpandido(Graphics2D g) {
        List<Quadrado> aux;
        aux = obstaculos;
        Quadrado temp;

        if (!aux.isEmpty()) {
            for (Quadrado obj : aux) 
            {
                    // Expandir
                    obj.expandirQuadro(20);////raio
                    // Define cor
                    g.setColor(Color.lightGray);
                    // Definir transparencia a expansao
                    g.setComposite(makeComposite((float) 0.3));
                    // Desenha a expansao
                    g.fillPolygon(obj.getxEx(), obj.getyEx(), obj.getyEx().length);
                    // Retorna o nivel de transparencia para os objetos seguintes
                    g.setComposite(makeComposite((float) 1.0));
            }
        }
    }

    private AlphaComposite makeComposite(float alpha) {
        int type = AlphaComposite.SRC_OVER;
        return (AlphaComposite.getInstance(type, alpha));
    }

    public void limparCampo() {
        obstaculos.clear();
    }

    public void addObstaculos(int x, int y, int tipo, boolean rotacionar, int angulo) {
        int xl;
        int yl;
        int valor = ua;
        if (tipo == 0) {
            valor = 4 * ua;
        } else if (tipo == 1) {
            valor = 8 * ua;
        } else if (tipo >= 1) {
            valor = 16 * ua;
        }
        xl = x / valor;
        xl = xl * valor;
        yl = y / valor;
        yl = yl * valor;
        Color cor = Color.GREEN;
        if (tipo == 1) {
            cor = Color.ORANGE;
        } else if (tipo > 1) {
            cor = Color.BLUE;
        }
        Quadrado obj = new Quadrado(xl, yl, valor, tipo, cor);

        if(rotacionar)
            obj = rotacionaObstaculo(obj, angulo);

        obstaculos.add(obj);
        Collections.sort(obstaculos, new Comparador_y());
        Collections.sort(obstaculos, new Comparador_x());
    }

    public void addObstaculos(int x, int y, int altura, int largura) {
        Quadrado obj = new Quadrado(x, y, altura, largura, 5, Color.white);
        obstaculos.add(obj);
        Collections.sort(obstaculos, new Comparador_y());
        Collections.sort(obstaculos, new Comparador_x());
    }

    public List<Quadrado> getObstaculos() {
        return obstaculos;
    }

    // Retorna -1 se a célula está CHEIA;
    // Retorna 0 se a célula está VAZIA;
    // Retorna 1 se a célula é MISTA;
    public int classificaCelula(int x1, int y1, int x2, int y2) {

        int x = x1;
        int y = y2;
        int altura = y1 - y2;
        int largura = x2 - x1;

        //System.out.println("Celula:: x: " + x + " y: " + y + " altura: " + altura + " largura: " + largura);
        Rectangle celula = new Rectangle(x, y, largura, altura);

        List<Quadrado> aux;
        aux = obstaculos;

        if (!aux.isEmpty()) {
            for (Quadrado obj : aux) {

                Polygon obstaculo = new Polygon(obj.getxEx(), obj.getyEx(), obj.getxEx().length);

                // Se a célula está cheia, ou seja:
                // Se está totalmente dentro do obstáculo, returna -1;
                if (obstaculo.contains(celula)) {
                    return -1;
                }

                // Varre cada ponto do obstáculo para verificar
                // se pelo menos um ponto está dentro da célula;
                for (int i = 0; i < obj.getxEx().length; i++) {
                    Point p = new Point(obj.getxEx()[i], obj.getyEx()[i]);
                    // Se pelo menos um ponto do obstaculo está dentro da célula, retorna 1;
                    if (celula.contains(p)) {
                        return 1;
                    }
                }

                //Verificar as laterais sem ponto
                if (obstaculo.intersects(celula)) {
                    return 1;
                }

            }
        }
        // Se a célula está vazia, retorna 0;
        return 0;
    }

    private Quadrado rotacionaObstaculo(Quadrado obj, int angulo) {

        int[] xLinha = new int[obj.getX().length];
        int[] yLinha = new int[obj.getY().length];

        int mundoX = (obj.getX()[1]-obj.getX()[0]);
            mundoX = mundoX/2 + obj.getX()[0];
        int mundoY = (obj.getY()[2]-obj.getY()[0]);
            mundoY = mundoY/2 + obj.getY()[0];

        for(int i = 0; i < obj.getX().length; i++) {
            xLinha[i] = (int) (((obj.getX()[i]-mundoX)* Math.cos(angulo * Math.PI / 180)) -
                    ((obj.getY()[i]-mundoY) * Math.sin(angulo * Math.PI / 180)));
            xLinha[i] += mundoX;

            yLinha[i] = (int) (((obj.getX()[i]-mundoX)* Math.sin(angulo * Math.PI / 180)) +
                    ((obj.getY()[i]-mundoY) * Math.cos(angulo * Math.PI / 180)));
            yLinha[i] += mundoY;
        }

        obj.setX(xLinha);
        obj.setY(yLinha);
        obj.setAng(angulo);

        return obj;
    }
    
}

class Comparador_x implements Comparator {

    public int compare(Object obj1, Object obj2) {
        Quadrado c1 = (Quadrado) obj1;
        Quadrado c2 = (Quadrado) obj2;
        return c1.getX()[0] - c2.getX()[0];
    }
}

class Comparador_y implements Comparator {

    public int compare(Object obj1, Object obj2) {
        Quadrado c1 = (Quadrado) obj1;
        Quadrado c2 = (Quadrado) obj2;
        return c1.getY()[0] - c2.getY()[0];
    }
}
